package com.tianji.learning.handler;

import com.tianji.common.utils.DateUtils;
import com.tianji.learning.constants.RedisConstants;
import com.tianji.learning.pojo.po.PointsBoard;
import com.tianji.learning.service.IPointsBoardSeasonService;
import com.tianji.learning.service.IPointsBoardService;
import com.tianji.learning.util.TableInfoContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

import static com.tianji.learning.constants.LearningConstants.POINTS_BOARD_TABLE_PREFIX;

@Component
@RequiredArgsConstructor
public class PointsBoardPersistentHandler {

    private final IPointsBoardSeasonService seasonService;

    private final IPointsBoardService pointsBoardService;

    private final StringRedisTemplate redisTemplate;


    @XxlJob("savePointsBoard2DB")
    public void savePointsBoard2DB() {

        LocalDateTime localDateTime = LocalDateTime.now().minusMonths(1);

        Integer season = seasonService.querySeasonByTime(localDateTime);
        if (season == null) {
            return;
        }
        // 将表名存入ThreadLocal
        TableInfoContext.setInfo(POINTS_BOARD_TABLE_PREFIX + season);

        // 查询榜单数据
        String key = RedisConstants.POINT_BOARD_KEY_PREFIX + localDateTime.format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER);
        // 分页查询Redis数据


        int shardIndex = XxlJobHelper.getShardIndex();
        int total = XxlJobHelper.getShardTotal();

        int page = shardIndex + 1; // 分片序号+1
        int pageSize = 100;

        while (true) {
            List<PointsBoard> boardList = pointsBoardService.queryCurrentBoardList(key, page, pageSize);
            if (boardList.isEmpty()) {
                break;
            }

            // 将排行榜数据持久化到数据库
            // 将排名信息写入到id，通过表示排名
            boardList.forEach(pointsBoard -> {
                pointsBoard.setId(pointsBoard.getRank().longValue());
                pointsBoard.setRank(null);
            });

            pointsBoardService.saveBatch(boardList);
            // 翻页，跳过N页，N为分片数量
            page += total;
        }
        // 持久化完成后删除ThreadLocal中的数据
        TableInfoContext.remove();
    }

    @XxlJob("createTableJob")
    public void createPointBoardTable() {
        // 1.获取上月时间
        LocalDateTime time = LocalDateTime.now().minusMonths(1);
        // 2.查询赛季id
        Integer season = seasonService.querySeasonByTime(time);
        if (season == null) {
            // 赛季不存在
            return;
        }
        // 3.创建表
        pointsBoardService.createPointBoardTable(season);
    }

    @XxlJob("clearPointBoardFromRedis")
    public void clearPointBoardFromRedis() {
        // 1.获取上月时间
        LocalDateTime time = LocalDateTime.now().minusMonths(1);
        // 2.计算key
        String key = RedisConstants.POINT_BOARD_KEY_PREFIX + time.format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER);

        redisTemplate.unlink(key);
    }

}